//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using GenericGridControl.Model;
using OpenLS.Spreadsheet.Expressions;
using OpenLS.Spreadsheet.Internals;
using OpenLS.Spreadsheet.UI.Internals.Resources;
using OpenLS.UI;
using OpenLS.Spreadsheet.UI.Internals;
using QuantumWorkspace.SessionManager;
using QuantumWorkspaces.DomainEntities;

namespace OpenLS.Spreadsheet.UI
{
    class GridFindReplace
    {
        public static void EnableCommands(UIElement g)
        {
            g.CommandBindings.Add(new CommandBinding(ApplicationCommands.Find, onFind, onHasWorksheet));
            g.CommandBindings.Add(new CommandBinding(ApplicationCommands.Replace, onReplace, onHasWorksheet));
            //AddFindStuff(g, OnFindFormulas);
            addFindCommand(g, SpreadsheetCommands.FindFormulas, c => c.Formula != null);
            addFindCommand(g, SpreadsheetCommands.FindComments, c => c.Comment != null);
            addFindCommand(g, SpreadsheetCommands.FindConditionalFormatting, c => c.ConditionalFormattings != null);

        }

        private static void addFindCommand(UIElement g, ICommand command, Predicate<Cell> predicate)
        {
            g.CommandBindings.Add(new CommandBinding(command,
                                                     (sender, e) => onFindWithPredicate(sender, e,
                                                                                    predicate), onHasWorksheet));
        }

        private static void onFindWithPredicate(object sender, RoutedEventArgs e, Predicate<Cell> predicate)
        {
            Worksheet ws = getWorksheet(sender);
            IEnumerable<Cell> cells = Enumerable.Where(ws.GetCells(), predicate);
            ws.Selection = RangeBuilder.GetRange(cells);
            e.Handled = true;
        }

        private static Worksheet getWorksheet(object sender)
        {
            return WorksheetHelper.GetWorksheet(sender);
        }

        private static void onHasWorksheet(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = getWorksheet(sender) != null;
            args.Handled = true;
        }

        private static Window getWindow(object sender)
        {
            var e = sender as FrameworkElement;
            while (e != null)
            {
                var w = e as Window;
                if (w != null)
                    return w;
                if (e.Parent == null)
                    e = e.TemplatedParent as FrameworkElement;
                else
                    e = e.Parent as FrameworkElement;
            }
            return null;
        }

        static void onFind(object sender, object args)
        {
            Worksheet currentWorksheet = getWorksheet(sender);
            if (currentWorksheet == null)
                return;
            FindAndReplaceControl w = getFindAndReplaceWindow(sender, currentWorksheet);
            w.Mode = FindAndReplaceMode.Find;
            WindowServices.Show(w, OpenLS.UI.Internals.UIStringTable.FindAndReplace, sender as UIElement);
            //            w.Show();
        }

        static FindAndReplaceControl getFindAndReplaceWindow(object sender, Worksheet worksheet)
        {
            Window p = getWindow(sender);
            var r = new FindAndReplaceControl(worksheet);
            return r;
        }

        static void onReplace(object sender, object args)
        {
            Worksheet currentWorksheet = getWorksheet(sender);
            if (currentWorksheet == null)
                return;
            FindAndReplaceControl w = getFindAndReplaceWindow(sender, currentWorksheet);
            w.Mode = FindAndReplaceMode.Replace;
            WindowServices.Show(w, OpenLS.UI.Internals.UIStringTable.FindAndReplace, sender as UIElement);
            //  w.Show();
        }
    }
    static class GridUse
    {
        public static void EnableCommands(UIElement g)
        {
            g.CommandBindings.Add(new CommandBinding(SpreadsheetCommands.DeleteSheet, onDeleteSheet, onCanDeleteSheet));
            g.CommandBindings.Add(new CommandBinding(SpreadsheetEditingCommands.SetBackgroundPicture, onSetBackground, onHasNoBackground));
            g.CommandBindings.Add(new CommandBinding(SpreadsheetEditingCommands.DeleteBackgroundPicture, onDeleteBackground, onHasBackground));
            g.CommandBindings.Add(new CommandBinding(SpreadsheetCommands.NameManager, onNameManager, onHasWorksheet));
            g.CommandBindings.Add(new CommandBinding(SpreadsheetCommands.BigDataTableManager, onBigTableNameManager, onIsLoggedWithWorksheet));
            g.CommandBindings.Add(new CommandBinding(SpreadsheetCommands.Login, onLogin, onIsNotLogged));
            g.CommandBindings.Add(new CommandBinding(SpreadsheetCommands.Logout, onLogout, onIsLogged));
            g.CommandBindings.Add(new CommandBinding(SpreadsheetCommands.Register, onRegister, onIsNotLogged));
            
        }

        static Worksheet getWorksheet(object sender)
        {
            return WorksheetHelper.GetWorksheet(sender);
        }
        static void onHasWorksheet(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = getWorksheet(sender) != null;
            args.Handled = true;
        }

        static void onIsNotLogged(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = !QuantumUserSession.IsLogged;
            args.Handled = true;
        }

        static void onIsLogged(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = QuantumUserSession.IsLogged;
            args.Handled = true;
        }

        static void onIsLoggedWithWorksheet(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = (QuantumUserSession.IsLogged && (getWorksheet(sender) != null));
            args.Handled = true;
        }

        static Workbook getWorkbook(object sender)
        {
            Worksheet ws = getWorksheet(sender);
            if (ws != null)
                return ws.Workbook;
            return null;
        }

        static void onDeleteSheet(object sender, ExecutedRoutedEventArgs args)
        {

            Workbook wb = getWorkbook(sender);
            if (wb == null)
                return;
            args.Handled = true;
            wb.RemoveActiveSheet();
        }
        static void OnCanInsertSheet(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = true;
        }
        static void onCanDeleteSheet(object sender, CanExecuteRoutedEventArgs args)
        {
            Workbook workbook = SpreadsheetElement.GetWorkbook((DependencyObject) sender);
            args.CanExecute = !workbook.AreSheetsProtected && workbook.Sheets.Count > 1;
            args.Handled = true;
        }
        static void onHasNoBackground(object sender, CanExecuteRoutedEventArgs args)
        {
            args.Handled = true;
            Worksheet currentWorksheet = getWorksheet(sender);
            if (currentWorksheet == null)
                return;
            args.Handled = true;
            args.CanExecute = currentWorksheet.Background == null;
        }
        static void onHasBackground(object sender, CanExecuteRoutedEventArgs args)
        {
            Worksheet currentWorksheet = getWorksheet(sender);
            if (currentWorksheet == null)
                return;
            args.Handled = true;
            args.CanExecute = currentWorksheet.Background != null;
        }

        static void onSetBackground(object sender, ExecutedRoutedEventArgs args)
        {
            Worksheet currentWorksheet = getWorksheet(sender);
            if (currentWorksheet == null)
                return;
            try
            {
                var d = new OpenFileDialog
                                       {
                                           InitialDirectory =
                                               Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
                                           RestoreDirectory = true
                                       };
                if (d.ShowDialog(WindowServices.GetAncestor<Window>(sender)).GetValueOrDefault())
                {
                    var image = new BitmapImage {CacheOption = BitmapCacheOption.OnLoad};
                    image.BeginInit();
                    image.StreamSource = d.OpenFile();
                    image.EndInit();
                    currentWorksheet.Background = image;
                }
                args.Handled = true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        static void onDeleteBackground(object sender, ExecutedRoutedEventArgs args)
        {
            Worksheet currentWorksheet = getWorksheet(sender);
            if (currentWorksheet == null)
                return;
            currentWorksheet.Background = null;
        }
        static void onNameManager(object sender, object args)
        {
            Worksheet currentWorksheet = getWorksheet(sender); 
            if (currentWorksheet == null)
                return;
            var w = new NameManagerControl {DataContext = currentWorksheet};
            WindowServices.ShowDialog(w, UIStringTable.NameManager, 
                null, null,  o => false);
        }

        //

        static void onBigTableNameManager(object sender, object args)
        {
            Worksheet currentWorksheet = getWorksheet(sender);
            if (currentWorksheet == null)
                return;

            
            var w = new TableNameManagerControl { DataContext = currentWorksheet };
            WindowServices.ShowDialog(w, UIStringTable.NameManager,
                null, null, o => false);
        }

        private static void onLogin(object sender, object args)
        {
            var loginControl = new LoginControl();
            WindowServices.ShowDialogOkCancel<LoginControl>(loginControl, UIStringTable.Login,
                                                            null,
                                                            delegate
                                                                {
                                                                },
                                                            delegate
                                                                {
                                                                }
                );
        }

        private static void onLogout(object sender, object args)
        {
            QuantumUserSession.IsLogged = false;
        }

        private static void onRegister(object sender, object args)
        {
            var registerControl = new RegisterControl();
            WindowServices.ShowDialogOkCancel<RegisterControl>(registerControl, UIStringTable.Login,
                                                             null,
                                                             delegate
                                                             {
                                                             },
                                                             delegate
                                                             {
                                                             }
                 );
        }

    }
}
